# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0
from selenium.webdriver.common.action_chains import ActionChains
import unittest
import random
import time
from cookies import lasthopes, randomword
import cookies
import re
import string
import sys
from selenium.webdriver.common.keys import Keys
from PIL import Image
from os import remove, listdir, sep, makedirs
from os.path import basename, isfile, exists
import tempfile
from warnings import warn
import shutil
from httplib import CannotSendRequest


class BaseClass(unittest.TestCase):
##    def __init__(self, testname, isauth=False):
##        self.isauth = isauth
##        super(BaseClass, self).__init__(testname)
    def wait_for_popub_name(self, name):
        return [p for p in WebDriverWait(self.driver, timeout=8)\
                           .until(lambda dr: dr.find_elements_by_css_selector("div.b-popup-h"))\
                                if p.find_element_by_css_selector("div.b-popup-head-title")\
                                .text==name][0]
    def removeflock(self):
        while True:
            try: 
                WebDriverWait(self.driver, timeout=1).until(lambda dr: dr\
                                                        .find_element_by_tag_name("ins")).click()
            except: print "Gotta CannotSendRequest"
            time.sleep(4)
            #except CannotSendRequest: print "No <ins /> found. If flocktory still shown, try another method."



    def auth(self):
        driver = self.driver
        #Link to auth
        inputElement = driver.find_element_by_css_selector("div.b-header-top-auth")\
                             .find_element_by_css_selector("span.g-pseudo-h")
        inputElement.click()
        #Auth popup
        auth_pop = WebDriverWait(driver, timeout=10)\
                   .until(lambda dr: [p for p in dr.find_elements_by_css_selector("div.b-popup-h")\
                                      if p.find_element_by_css_selector("div.b-popup-head-title")\
                                      .text==u'Авторизация'])[0]
        #Auth button
        auth_btn = WebDriverWait(auth_pop, timeout=10)\
                   .until(lambda dr: dr.find_element_by_css_selector("input.b-sbutton-input"))
        #Credentials
        inp_mail = auth_pop.find_element_by_name('email')
        inp_pass = auth_pop.find_element_by_name('password')
        inp_mail.send_keys("sotmail.sotm@yandex.ru")
        inp_pass.send_keys('132785')
        auth_btn.click()
        url_before = driver.current_url
        #Wait for auth popup dissapeared
        WebDriverWait(driver, timeout=10)\
                   .until(lambda dr: not self.check_exists(auth_pop))
        #Wait for auth link dissapeared
        WebDriverWait(driver, timeout=10)\
                   .until(lambda dr: not self.check_exists(inputElement))
        #Wait for link to cabinet
        a = WebDriverWait(driver, timeout=10)\
                   .until(lambda dr: dr.find_element_by_css_selector("a.b-header-top-auth-profile-anchor.js-construct"))
        assert u'Личный кабинет' in a.text

    def clean_shit(self):
        try:
            fancyclc = WebDriverWait(self.driver, timeout=2)\
                                    .until(lambda dr: dr.find_element_by_css_selector("div.sp-fancybox-item.sp-fancybox-close"))
            fancyclc.click()
            WebDriverWait(driver, timeout=3).until(lambda dr: not self.check_exists(fancyclc))
        except: print "No fancy fucking toolbox found. Good."

    def get_url(self, urlpart=""):
        if len(self.urlappendix):
            if not "?" in urlpart: urlappendix = "?"+self.urlappendix
            else: urlappendix = "&"+self.urlappendix
        else:
            urlappendix = ""
        self.driver.get(self.baseurl+urlpart+urlappendix)

    def setUp(self):
        self.variables = cookies
        self.appendix = str(self.__class__).replace("<class \'", "")\
                                           .replace("\'>", "")\
                                           .split(".")[-1]
        print "Now running "+str(self.__class__)
        params = {'baseurl':"www.sotmarket.ru",\
                  'auth':0,\
                  'dev':0}
        for param in sys.argv[1:]:
            key, val = param.split("=")
            params[key] = int(val) if val in ["0", "1"] else val
        if params['dev']:
            self.urlappendix="test"
        else:
            self.urlappendix=""
        self.baseurl = "http://"+params['baseurl']
        self.driver = webdriver.Firefox()
        self.driver.maximize_window()
        self.get_url()
        if params['auth']:
            self.auth()
            self.isauth=True
        else:
            self.isauth=False
        # Append cookies to prevent lasthope popups
        for lasthope in lasthopes:
            self.driver.add_cookie(lasthope)
        self.remove_by_css("overlay-fixed")
        #Refresh page to send cookies
        self.clean_shit()
        self.driver.refresh()
        try:
            if self.clear_cart and self.clear_cart.__name__: self.clear_cart()
        except: print "Call cart clear failed"
        self.verificationErrors = []
        self.accept_next_alert = True
        self.shot_count = 0
        self.tempdir = tempfile.gettempdir()
        self.faildir = self.tempdir+sep+"fails"
        files = [self.tempdir+sep+f for f in listdir(self.tempdir) if isfile(self.tempdir+sep+f) and re.match(self.appendix+'__.*\.png', f)]
        for f in files:
            remove(f)
        if not exists(self.faildir):
            makedirs(self.faildir)
            print self.faildir+" was created"
        else:
            for f in [self.faildir+sep+f for f in listdir(self.faildir) if isfile(self.faildir+sep+f) and re.match(self.appendix+'__.*(\.png|\.txt)', f)]:
                remove(f)
            print self.faildir+" was cleaned"
        print "Screenshots will be saved into "+self.tempdir
        self.clean_shit()

    def shot_an_element(self, element, name, crop=True):
        self.shot_count+=1
        path = self.tempdir+sep+self.appendix+'__'+str(self.shot_count)+'-'+name+'.png'
        self.driver.save_screenshot(path) # saves screenshot of entire page
        try:
            location = element.location
            size = element.size
            if crop:
                im = Image.open(path) # uses PIL library to open image in memory
                left = max(location['x']-32, 0)
                top = max(location['y']-32, 0)
                right  = min(location['x'] + size['width']+32, im.size[0])
                bottom = min(location['y'] + size['height']+32, im.size[1])
                im = im.crop((left, top, right, bottom)) # defines crop points
                im.save(path) # saves new cropped image
            return True
        except:
            print "shot the element on "+path+" failed"
            return False
    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException, e: return False
        return True
    
    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException, e: return False
        return True
    
    def check_exists(self, element):
        try:
            WebDriverWait(self.driver, timeout=1)\
                   .until(lambda dr: element.is_enabled())
            return True
        except: return False
    
    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True
    def remove_by_css(self, selector):
        self.driver.execute_script(\
            "try{\
                 var element = document.getElementsByClassName(\'"+selector+"\')[0];\
                 element.parentNode.removeChild(element);\
             }\
             catch(e){console.log(e.stack);}")      
        
    def find_error_tooltip(self, element, text):
        self.clean_shit()
        self.remove_by_css("overlay-fixed")
        berrs = element.find_elements_by_css_selector("div.b-input-error")+\
                element.find_elements_by_css_selector("div.state_error")
        berr = WebDriverWait(self.driver, timeout=10)\
               .until(lambda dr: [br for br in berrs if br.is_displayed()==True])[0]
        hov = ActionChains(self.driver).move_to_element(berr)
        hov.perform()
        tooltip = WebDriverWait(self.driver, timeout=3)\
                  .until(lambda dr: dr.find_element_by_css_selector("div.b-tooltip.scheme_red")
                                      .find_element_by_css_selector("div.b-tooltip-body"))
        assert text in tooltip.text,\
               "\'"+text+"\' not matched by \'"+tooltip.text+"\'"

    def run(self, result=None):
        self.currentResult = result # remember result for use in tearDown
        unittest.TestCase.run(self, result)
        
    def tearDown(self):
        self.shot_an_element(self.driver.find_element_by_tag_name("body"), "full_page-end", False)
        wh = str(self.driver.execute_script("return screen.width;"))+"x"+\
             str(self.driver.execute_script("return screen.height;"));
        self.driver.quit()
        #self.assertEqual([], self.verificationErrors)
        ok = self.currentResult.wasSuccessful()
        errors = self.currentResult.errors
        failures = self.currentResult.failures
        print ' All tests passed so far!' if ok else \
                ' %d errors and %d failures so far' % \
                (len(errors), len(failures))
        if not ok:
            failscrs = [self.tempdir+sep+f for f in listdir(self.tempdir)\
                        if isfile(self.tempdir+sep+f) and \
                        re.match(self.appendix+'__.*\.png', f)]
            for failscr in failscrs: shutil.copy(failscr, self.faildir)
            for error in errors:
                errfile = open(self.faildir+sep+str(error[0]).split(" ")[0]+"__error.txt", "w")
                errfile.write(wh+'\n'+'\n'.join(error[1:]))
                errfile.close()
            for failure in failures:
                failfile = open(self.faildir+sep+str(failure[0]).split(" ")[0]+"__failure.txt", "w")
                failfile.write(wh+'\n'+'\n'.join(failure[1:]))
                failfile.close()

    def wait_pop_with_any_text(self, texts):
        pops = WebDriverWait(self.driver, timeout=6)\
                .until(lambda dr: dr.find_elements_by_css_selector("div.b-popup-h"))
        fpops = filter(lambda a: any(map(lambda x: x in a.text, texts)), pops)
        if len(fpops): return fpops[0]
        else: return False

